<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <title>ReactiveElement example</title>
    <link rel="stylesheet" href="demos.css" />
  </head>

  <body role="main">
    <!--
  Note: This demo page puts its template and script in the document body, which
  is somewhat unusual, and only necessary to support showing this demo inline in
  the Elix documentation. In a typical page, the template and script would go in
  the document head.
  -->
    <div class="demo padded">
      <template id="incrementDecrementTemplate">
        <button id="decrement">-</button>
        <span id="value"></span>
        <button id="increment">+</button>
      </template>

      <script type="module">
        import {
          defaultState,
          firstRender,
          ids,
          render,
          setState,
          state,
          template,
        } from "../src/base/internal.js";

        import ReactiveElement from "../src/core/ReactiveElement.js";

        // Create a native web component with reactive behavior.
        class IncrementDecrement extends ReactiveElement {
          // This sets the component's initial state at constructor time.
          get [defaultState]() {
            return Object.assign(super[defaultState], {
              value: 0,
            });
          }

          // Render the current state to the DOM.
          [render](changed) {
            super[render](changed);

            if (this[firstRender]) {
              this[ids].decrement.addEventListener("click", () => {
                this.value--;
              });
              this[ids].increment.addEventListener("click", () => {
                this.value++;
              });
            }

            if (changed.value) {
              this[ids].value.textContent = this[state].value;
            }
          }

          // This template is cloned to create the shadow tree for a new element.
          get [template]() {
            return incrementDecrementTemplate;
          }

          // Provide a public property that gets/sets state.
          get value() {
            return this[state].value;
          }
          set value(value) {
            this[setState]({ value });
          }
        }

        customElements.define("increment-decrement", IncrementDecrement);
      </script>

      <increment-decrement></increment-decrement>
    </div>
  </body>
</html>
